#pragma once


#include <iostream>
#include <string>
#include <functional>
#include "InetAddr.hpp"

class Reactor;
class Connection;
using handler_t = std::function<void(Connection* conn)>;

#define ListenConnection 0
#define NormalConnection 1

// Connection 只需要对成员做基本的操作 
// 使用回调去设置处理方法 
class Connection
{
private:
public:
    Connection(int fd)
        : _sockfd(fd)
    {}

    void RegisterHandler(handler_t recver, handler_t sender, handler_t excepter)
    {
        _handler_recver = recver;
        _handler_sender = sender;
        _handler_excepter = excepter;
    }

    void SetEvents(uint32_t events)
    {
        _events = events;
    }

    uint32_t GetEvents()
    {
        return _events;
    }

    int GetSockfd()
    {
        return _sockfd;
    }

    handler_t HandlerRecver()
    {
        return _handler_recver;
    }

    handler_t HandlerSender()
    {
        return _handler_sender;
    }

    handler_t HandlerExcepter()
    {
        return _handler_excepter;
    }

    void SetReactor(Reactor* R)
    {
        _R = R;
    }

    Reactor* GetReactor()
    {
        return _R;
    }

    void SetConnectionType(int type)
    {
        _type = type;
    }

    int GetConnectionType()
    {
        return _type;
    }

    const InetAddr& GetInetAddr()
    {
        return _addr;
    }

    void SetAddr(const InetAddr& addr)
    {
        _addr = addr;
    }

    void AppendInBuffer(const std::string& in)
    {
        _inbuffer += in;
    }

    void AppendOutBuffer(const std::string& in)
    {
        _outbuffer += in;
    }

    std::string& GetInbuffer()
    {
        return _inbuffer;
    }

    std::string& GetOutbuffer()
    {
        return _outbuffer;
    }

    void DiscardOutbuffer(int n)
    {
        _outbuffer.erase(0, n); 
    }

    void Closefd()
    {
        if (_sockfd >= 0)
        {
            ::close(_sockfd);
        }
    }

    ~Connection()
    {}

private:
    int _sockfd;
    uint32_t _events;

    // 套接字类型
    int _type;

    // 连接的客户端信息 
    InetAddr _addr;

    // 使用 string 充当缓冲区 
    std::string _inbuffer;  // 输入缓冲区 
    std::string _outbuffer; // 输出缓冲区 

    // 处理方法 
    handler_t _handler_recver;
    handler_t _handler_sender;
    handler_t _handler_excepter;

    // 回指自己所属的 Reactor 
    Reactor* _R = nullptr;
};


